# -*- coding: UTF-8 -*-
import tkinter as tk
from tkinter import ttk, scrolledtext, filedialog
from Code.View.sc_global import Global
from Code.View.sc_module import InfoText, ProgressBar
from Code.View.Datamation.sc_provide import view_gate


class WidgetsTemplate:

    @classmethod
    def create_widget(cls, types, master, width, height, values):
        return eval('cls.{}'.format(types))(master, width, height, values)

    @classmethod
    def clear_value(cls, widget):
        widget.clear()

    @classmethod
    def get_value(cls, widget, tab=None):
        return widget.get(tab)

    @classmethod
    def set_value(cls, widget, value, tab=None, has_md=False):
        widget.set(value, tab, has_md)

    @classmethod
    def add_tab(cls, widget, tab, value=None):
        """ 复合类型控件才有的tab增加方法 """
        widget.add(tab, value)

    @classmethod
    def remove_tab(cls, widget, tab):
        """ 复合类型控件才有的tab移除方法 """
        widget.remove(tab)

    class Label:
        def __init__(self, master, width, height, values):
            var = tk.StringVar()
            tk.Label(master, textvariable=var, anchor='w', justify="left", width=width,
                     height=height, font=(Global.G_TEXT_FONT, 10)).pack(side='left', padx=10)
            var.set('\n'.join(values))
            self.widget = var

    class Entry:
        def __init__(self, master, width, height, values):
            entry = ttk.Entry(master, width=width)
            entry.pack(side='left', padx=10, pady=2)
            if values:
                entry.insert(0, '\n'.join(values).strip())
            self.widget = entry

        def get(self, *args):
            return self.widget.get()

    class PasswordEntry:
        def __init__(self, master, width, height, values):
            def see_password(sw):
                entry['show'] = '' if sw else '*'
            entry = ttk.Entry(master, width=width, show='*')
            entry.pack(side='left', padx=10, pady=2)
            if values:
                entry.insert(0, '\n'.join(values).strip())
            btn = tk.Button(master, image=view_gate.query_photo_image_data('LGN_EYE'), bd=0)
            btn.pack(side='left')
            btn.bind("<Button-1>", lambda event: see_password(True))
            btn.bind("<ButtonRelease-1>", lambda event: see_password(False))
            self.widget = entry

        def get(self, *args):
            return self.widget.get()

    class MultiScaleBar:
        def __init__(self, master, width, height, values):
            self.master = master
            self.width = width
            self.height = height
            self.widget = {}
            for tab, value in values.items():
                self.add(tab, value)

        def set(self, value, tab, *args):
            self.widget[tab][1].update(value, colors=True)

        def add(self, tab, value=None):
            count = len(self.widget)
            row = int(count / Global.G_MULTI_COLUMN_LIMIT)
            row = row + 2 if row else 0
            column = count % Global.G_MULTI_COLUMN_LIMIT
            lab = tk.Label(self.master, text=tab)
            lab.grid(row=row, column=column)
            progress = ProgressBar(self.master, width=self.width, height=self.height, row=row + 1, column=column)
            if value and isinstance(value[0], int):
                progress.update(value[0], colors=True)
            self.widget[tab] = (lab, progress)

        def remove(self, tab):
            if tab in self.widget:
                lab, progress = self.widget[tab]
                lab.grid_remove()
                progress.destroy()

    class MultiScaleTab:
        def __init__(self, master, width, height, values):
            self.height = height
            self.widget = {}
            self.notebook = ttk.Notebook(master, width=width, height=height, style="App.TNotebook")
            self.notebook.pack(side='left')
            for tab, value in values.items():
                self.add(tab, value)

        def set(self, value, tab, *args):
            text = self.widget[tab][1]
            text.clear()
            for k, v in value:
                text.insert_progress(k, v)

        def add(self, tab, value=None):
            fm = tk.Frame(self.notebook)
            fm.pack()
            info_text = InfoText(fm, height=self.height)
            if value:
                info_text.insert_text('\n'.join(value))
            self.notebook.add(fm, text=tab)
            self.widget[tab] = (fm, info_text)

        def remove(self, tab):
            if tab in self.widget:
                self.notebook.forget(self.widget[tab][0])

    class Combobox:
        def __init__(self, master, width, height, values):
            combobox = ttk.Combobox(master, width=width, values=values, state='readonly')
            combobox.current(0)
            combobox.pack(side='left', padx=10, pady=2)
            self.widget = combobox

        def get(self, *args):
            return self.widget.get()

    class MultiCombobox:
        def __init__(self, master, width, height, values):
            self.master = master
            self.width = width
            self.widget = {}
            for tab, value in values.items():
                self.add(tab, value)

        def clear(self):
            for _, widget in self.widget.items():
                widget[1].set('')

        def get(self, tab):
            return self.widget[tab][1].get()

        def set(self, value, tab, *args):
            instance = self.widget[tab][1]
            instance['values'] = value
            instance.current(0)

        def add(self, tab, value=''):
            count = len(self.widget)
            row = int(count / Global.G_MULTI_COLUMN_LIMIT)
            row = row + 2 if row else 0
            column = count % Global.G_MULTI_COLUMN_LIMIT
            lab = tk.Label(self.master, text=tab)
            lab.grid(row=row, column=column)
            combobox = ttk.Combobox(self.master, width=self.width, values=value, state='readonly')
            if value:
                combobox.current(0)
            combobox.grid(row=row + 1, column=column, padx=10)
            self.widget[tab] = (lab, combobox)

        def remove(self, tab):
            if tab in self.widget:
                lab, combo = self.widget[tab]
                lab.grid_remove()
                combo.grid_remove()

    class Checkbox:
        def __init__(self, master, width, height, values):
            def select_all(event=None):
                for inst in vars:
                    inst.set(int(var.get()))

            var, vars = tk.IntVar(), []
            if len(values) > 1:
                ttk.Checkbutton(master, variable=var, command=select_all,
                                text=view_gate.query_language_data('SELECT_ALL')
                                ).grid(row=0, column=1, padx=10, sticky='w')
            for opt in values:
                row = int(len(vars) / Global.G_MULTI_COLUMN_LIMIT) + 1
                column = len(vars) % Global.G_MULTI_COLUMN_LIMIT + 1
                vars.append(tk.IntVar())
                ttk.Checkbutton(master, text=opt, width=width, variable=vars[-1]).grid(row=row, column=column, padx=10)
            self.widget = vars

        def get(self, *args):
            return [inst.get() for inst in self.widget]

    class FileButton:
        def __init__(self, master, width, height, values):
            def choose_file(var):
                local_path = filedialog.askopenfilename(filetypes=(("Custom files", values[0]),))
                var.set(local_path)

            entry_var = tk.StringVar()
            entry = ttk.Entry(master, width=width, textvariable=entry_var, state='disabled')
            entry.pack(side='left', padx=10)
            ttk.Button(master, text="...", width=3, command=lambda x=entry_var: choose_file(x)
                       ).pack(side='left', pady=2)
            self.widget = entry

        def get(self, *args):
            return self.widget.get()

    class Text:
        def __init__(self, master, width, height, values):
            text = scrolledtext.ScrolledText(master, font=(Global.G_DEFAULT_FONT, 10), bd=2, relief='ridge',
                                             bg='Snow', height=height, width=width)
            text.insert('end', '\n'.join(values))
            text.pack()
            self.widget = text

        def get(self, *args):
            return self.widget.get('1.0', 'end').strip()

    class InfoText:
        def __init__(self, master, width, height, values):
            info_text = InfoText(master, height=height)
            info_text.insert_text('\n'.join(values))
            self.widget = info_text

        def clear(self):
            self.widget.clear()

        def set(self, value, tab, has_md=False):
            value = '###### > {}\n{}\n'.format(tab, value)
            if has_md:
                self.widget.insert_markdown(value)
            else:
                self.widget.insert_text(value)

    class MultiInfoText:
        def __init__(self, master, width, height, values):
            self.height = height
            self.widget = {}
            self.notebook = ttk.Notebook(master, width=width, height=height, style="App.TNotebook")
            self.notebook.pack(side='left')
            for tab, value in values.items():
                self.add(tab, value)

        def set(self, value, tab, has_md=False):
            text = self.widget[tab][1]
            text.clear()
            if has_md:
                text.insert_markdown(value)
            else:
                text.insert_text(value)

        def add(self, tab, value=None):
            fm = tk.Frame(self.notebook)
            fm.pack()
            info_text = InfoText(fm, height=self.height)
            if value:
                info_text.insert_text('\n'.join(value))
            self.notebook.add(fm, text=tab)
            self.widget[tab] = (fm, info_text)

        def remove(self, tab):
            if tab in self.widget:
                self.notebook.forget(self.widget[tab][0])

    class MultiPlotTab:
        def __init__(self, master, width, height, values):
            self.height = height
            self.widget = {}
            self.values = {}
            self.notebook = ttk.Notebook(master, width=width, height=height, style="App.TNotebook")
            self.notebook.pack()
            for tab, value in values.items():
                self.add(tab, value)

        def set(self, value, tab, *args):
            text = self.widget[tab][1]
            text.clear()
            if isinstance(value, str):
                text.insert_text(value)
            else:
                text.insert_image(value)

        def add(self, tab, value=None):
            fm = tk.Frame(self.notebook)
            fm.pack()
            info_text = InfoText(fm, height=self.height)
            data_file = ''
            if value:
                data_file = value[0]
                info_text.insert_text(data_file)
            self.values[tab] = data_file
            self.notebook.add(fm, text=tab)
            self.widget[tab] = (fm, info_text)

        def remove(self, tab):
            if tab in self.widget:
                self.notebook.forget(self.widget[tab][0])

        def get_data_file_and_plot_params(self, tab):
            value = self.values[tab]
            if value:
                return value, None
            values = self.widget[tab][1].get_text().strip().split('\n')
            return values[0], values[1]
